iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
1
Mobile Development

新手試試用Flutter做Netflix UI系列 第 18

[Day18]Flutter Netflix UI 更多頁面 Flexible

  • 分享至 

  • xImage
  •  

大家今天做的是更多頁面,今天用到比較不同有Flexible、 FlatButton.icon

Flexible (Flutter Widget of the Week)

切換使用者

使用中的人,頭像比較大,但是Padding看起來是一樣的,這個一開始幾十分鐘沒做出來,最後突然想起有Flexible可以用,Flexible可以讓Column或Row底下的Widget按比例分配空間,之前一直使用Expanded都給忘記了

為了讓頭像跟名字是一樣寬度,我的作法是頭像一個Row排列,名字一個Row排列,各自用Flexible分配空間

 _buildUserList(List<User> users, int selectedIndex) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: List.generate(
              5,
              (index) =>
                  _buildUserItemImage(_users[index], index, selectedIndex)),
        ),
        Row(
          children: List.generate(
              5,
              (index) =>
                  _buildUserItemName(_users[index], index, selectedIndex)),
        )
      ],
    );
  }

正在使用的人,Flexible的flex設為4,其他人為3,這樣他們就會按照4:3:3:3:3分配這個Row的寬度

_buildUserItemImage(User user, int index, int selectedIndex) {
  return Flexible(
    flex: selectedIndex == index ? 4 : 3,
    child: GestureDetector(
      onTap: () {
        _selectedIndex = index;
        setState(() {
          print("selectedIndex :$selectedIndex");
        });
      },
      child: Container(
        margin: EdgeInsets.symmetric(horizontal: 8.0),
        child: Stack(
          alignment: Alignment.topCenter,
          children: [
            Image.asset(user.assetName),
          ],
        ),
      ),
    ),
  );
}


_buildUserItemName(User user, int index, int selectedIndex) {
  return Flexible(
    flex: selectedIndex == index ? 4 : 3,
    child: Align(
      alignment: Alignment.bottomCenter,
      child: Text(user.name,style: TextStyle(color: selectedIndex ==index? Colors.white:Colors.grey),),
    ),
  );
}

管理使用者按鍵

我按的時候發現這是個有波紋的按鍵,所以使用FlatButton
FlatButton.icon會有做一個Icon在前面,常見的帶一個Icon與文字的按鍵可以使用
類似的像是RaisedButton.icon、OutlineButton.icon都有這樣的按鍵
splashColor是波紋的顏色

 _buildEditButton() {
  return FlatButton.icon(
    splashColor: Colors.grey,
    icon: Icon(
      Icons.edit,
      color: labelStyle.color,
    ),
    onPressed: () {},
    label: Text(
      "管理使用者",
      style: labelStyle,
    ),
  );
}

分享連結給朋友

這一段主要是放了文字的排列

 _buildShareLink() {
  return Container(
    color: Colors.grey.withOpacity(0.2),
    padding: EdgeInsets.all(8.0),
    child: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Row(
          children: [
            Icon(Icons.message),
            Text(
              " 將 Netflix 介紹給朋友。",
              style: titleStyle,
            )
          ],
        ),
        Text(
          "將此連結分享給朋友,讓他們也可以一起討論您最喜愛的節目與電影。",
          style: textStyle,
        ),
        Text(
          "條款與條件",
          style: textStyle2,
        ),
        Container(
          color: Colors.black,
          child: Row(
            children: [
              Expanded(child: Text("https://www.netflix.com/browse/saiosfhaisfjaosfasf",maxLines: 1,overflow: TextOverflow.ellipsis,)),
              FlatButton(onPressed: (){}, child: Text("複製連結"),color: Colors.white,)
            ],
          ),
        ),
        SizedBox(height: 16.0,),
        Row(
          mainAxisSize: MainAxisSize.max,
          children: [
            _buildShareIcon("Line", "assets/icons/line.png"),
            _buildDivider(),
            _buildShareIcon("Facebook",   "assets/icons/facebook.png"),
           _buildDivider(),
          _buildShareIcon("Gmail",   "assets/icons/Gmail-icon.png"),
            _buildDivider(),

            Expanded(
              child: Column(
                children: [
                  Container(
                    margin: EdgeInsets.all(4.0),
                      width: 30.0,
                      height: 30.0,
                      child: Icon(Icons.more_horiz)),
                  Text("更多")
                ],
              ),
            ),

          ],
        )
      ],
    ),
  );
}

 _buildShareIcon(String title,String assetName){
  return   Expanded(
    child: Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(4.0),
          child: Image.asset(assetName,width: 30,height: 30,),
        ),
        Text(title)
      ],
    ),
  );
}
_buildDivider(){
  return    Container(width: 2,
    height: 40,
    color: Colors.grey.withOpacity(0.6),);
}

有一行要排分享到Facebook或Line的地方,因為是平均分配,所以直接使用Expanded,Expanded其實也是繼承Flexible

class Expanded extends Flexible {
/// Creates a widget that expands a child of a [Row], [Column], or [Flex]
/// so that the child fills the available space along the flex widget's
/// main axis.
const Expanded({
  Key key,
  int flex = 1,
  @required Widget child,
}) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
}

附上今天完成的效果圖
Day18

如果大家有更好的寫法,請多指教,謝謝!

GitHub連結: flutter-netflix-clone


上一篇
[Day17]Flutter Netflix UI 編輯使用者頁面
下一篇
[Day19]Flutter Netflix UI App 設定頁面
系列文
新手試試用Flutter做Netflix UI30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言